<HTML><HEAD><TITLE>define_macro(++TermClass, ++TransPred, ++Options)</TITLE>
</HEAD><BODY>[ <A HREF="index.html">Obsolete</A> | <A HREF="../../index.html">Reference Manual</A> | <A HREF="../../fullindex.html">Alphabetic Index</A> ]
<H1>define_macro(++TermClass, ++TransPred, ++Options)</H1>
Defines a macro transformation for the functor or type specified by
TermClass.  The transformation predicate is TransPred and Options is a list
of options.


<DL>
<DT><EM>TermClass</EM></DT>
<DD>Term in the form Atom, Atom/Integer or type(Type).
</DD>
<DT><EM>TransPred</EM></DT>
<DD>Term in the form Atom/Integer.
</DD>
<DT><EM>Options</EM></DT>
<DD>Possibly empty list of option flags.
</DD>
</DL>
<H3>This built-in predicate is obsolete!</H3>
<H2>Description</H2>
   This predicate is used to define a macro transformation on a class of
   terms.  Macro transformation can be performed in two different
   situations, when a term is read by one of the read predicates (read
   macros) and when a term is written by one of the write predicates (write
   macros).

<P>
   The TermClass specifies to which terms the transformation will be
   applied:

<P>
Name/Arity transform all terms with the specified functor

<P>
type(Type) transform all terms of the specified type, where Type is one of
    compound, string, integer, rational, float, breal, goal, atom, meta.

<P>
   The +TransPred argument specifies the predicate that will perform the
   transformation.  TransPred must be of arity 2 or 3 and be in the form:
    trans_function(OldTerm, NewTerm [, Module]):- ... .

<P>
   At transformation time, the system will call TransPred in the module
   where define_macro/3 was invoked.  The term to transform is passed as
   the first argument, the second is a free variable which should be bound
   to the transformed term, and the optional third argument is the module
   where the term is read or written.

<P>
   Options is a list which may be empty (in this case the macro defaults to
   a local read term macro) or contain specifications from the following
   categories:

<P>
  * visibility

<P>
    local: The transformation is only visible in this module (default).

<P>
    global: The transformation is globally visible.

<P>
  * mode

<P>
    read: This is a read macro and shall be applied after reading a term
        (default).

<P>
    write: This is a write macro and shall be applied before printing a term.

<P>
  * type

<P>
    term: Transform all terms (default).

<P>
    clause: Transform only if the term is a program clause, i.e.  inside
        compile/1, assert/1 etc.  Write macros are applied using the 'C'
        option in the printf/2 predicate.

<P>
    goal: Write macros are applied when using the 'G' option in the
    	printf/2 predicate. Note that goal (read) macros are obsolete,
	please use inline/2 instead.

<P>
  * additional specification

<P>
    protect_arg: Disable transformation of subterms (optional).

<P>
    top_only: Consider only the whole term, not subterms (optional).

<P>
   A TermClass can have a read and a write macro attached at the same time.
   By default, macro transformations are local to the module where they
   were defined.  That means, only read/write built-ins that are called
   from inside this module do these transformations.  Local macros hide
   global ones.

<P>

<H3>Modes and Determinism</H3><UL>
<LI>define_macro(++, ++, ++) is det
</UL>
<H3>Exceptions</H3>
<DL>
<DT><EM>(4) instantiation fault </EM>
<DD>One or more arguments not instantiated.
<DT><EM>(5) type error </EM>
<DD>TermClass not of form Atom, Atom/Integer or type(Type).
<DT><EM>(5) type error </EM>
<DD>TransPred not of form Atom/Integer.
<DT><EM>(5) type error </EM>
<DD>Options not a list or contains invalid flags.
<DT><EM>(6) out of range </EM>
<DD>Arity of TransPred is not 2 or 3.
<DT><EM>(6) out of range </EM>
<DD>Illegal flag in Options.
<DT><EM>(161) macro transformation already defined in this module </EM>
<DD>Transformation already defined in the current module for    TermClass
</DL>
<H2>Examples</H2>
<PRE>
Success:
   % The following example illustrates how a/1 may be
   % transformed into b/2 using the reader.
   [eclipse]: [user].
    trans_a(a(X),b(X,10)).
    :-define_macro(a/1,trans_a/2,[]).

   yes.
   [eclipse]: read(X).
   &gt; a(fred).

   X = b(fred, 10)
   yes.

   %
   % Example showing use of protect_arg
   %
   [eclipse]: [user].
    ?- define_macro(b/1, trb/2, []),
       define_macro(b_protect/1, trb/2, [protect_arg]),
       define_macro(d/0, trd/2, []).
    trb(X, newfunctor(Arg)) :- arg(1, X, Arg).
    trd(d, newd).

   yes.
   [eclipse]: read(X1),read(X2).
   &gt; b(d).
   &gt; b_protect(d).

   X1 = newfunctor(newd)    % d is transformed
   X2 = newfunctor(d)       % d is not transformed
   yes.

   %
   % Example showing use of type macros
   %
    [eclipse 1]: [user].
     tr_int(0, 0).
     tr_int(N, s(S)) :- N &gt; 0, N1 is N-1, tr_int(N1, S).
     :- define_macro(type(integer), tr_int/2, []).

    yes.
    [eclipse 2]: read(X).
    3.

    X = s(s(s(0)))
    yes.

   %
   % Example showing use of write macros
   %
    [eclipse 1]: [user].
     tr_s(0, 0).
     tr_s(s(S), N) :- tr_s(S, N1), N is N1+1.
     :- define_macro(s/1, tr_s/2, [write]).

    yes.
    [eclipse 2]: write(s(s(s(0)))).
    3
    yes.


Error:
   define_macro(X, trx/2, []).              (Error 4).
   define_macro(a/1, tra/2, [c]).           (Error 6).



</PRE>
<H2>See Also</H2>
<A HREF="../../kernel/syntax/macro-3.html">macro / 3</A>, <A HREF="../../kernel/syntax/portray-3.html">portray / 3</A>, <A HREF="../../kernel/syntax/current_macro-4.html">current_macro / 4</A>, <A HREF="../../kernel/obsolete/erase_macro-1.html">erase_macro / 1</A>, <A HREF="../../kernel/control/phrase-2.html">phrase / 2</A>, <A HREF="../../kernel/control/phrase-3.html">phrase / 3</A>, <A HREF="../../kernel/compiler/inline-2.html">inline / 2</A>
</BODY></HTML>
